#ifndef __MULTI_TRACK_DEFINE_INCLUDE__
#define __MULTI_TRACK_DEFINE_INCLUDE__
#include <vector>
#include <queue>
#include "TentativeTrack.h"
#include "FIFO.h"
#include "../UKF/UKF_IMM.h"
#include "../AlgoUtility/algo_util.h"

enum MovementStatusCode {
	NotSure = 1,	//目标的移动状态暂时不确定
	Moveing = 2,	//目标正在移动
	Stop = 3		//目标已经停止
};

class TrackMovementItem_t :public algo_util::Point2D {
public:
	time_t timestamp;
	double sog;	//速度大小(m/s)
	double cog;
};

//记录目标移动状态信息
typedef struct TrackyMovementStatus {
	std::deque<TrackMovementItem_t>	history;		//目标的历史数据
	MovementStatusCode	status;						//目标当前的移动状态
	time_t stop_start_tm;							//目标停止状态开始的时间
	int		stop_duration;							//目标的停止状态持续时间
	time_t move_begin_tm;							//目标移动状态开始时间
	int	move_duration;								//目标移动状态持续时间
	double stay_location_lon;						//如果目标为停止状态，保存目标停留的位置的中心
	double stay_location_lat;					
	double stay_location_circle_r;					//停留位置漂移半径
}TrackyMovementStatus_t;

class TrackDetail {
public:
	unsigned int trackID;
	time_t	updateTime;
	double x;
	double y;
	double dx;
	double dy;
	double x_err;
	double y_err;
	size_t AtSize;
	double velocity_value;
	double velocity_heading;
	double residual_z_norm_value;
	TrackyMovementStatus_t		movement_status; //目标移动状态
	double lon;
	double lat;
	int history;					//已跟踪帧数
	int numberOfVisibleFrame;		//目标可见帧数
};
typedef std::vector<TrackDetail>  TrackDetailVector_t;

template<typename T>
class FixLengthQueue {
public:
	typedef std::queue<T> queue_t;
	FixLengthQueue(size_t length)
		:queue_len(length) {}

	void push(const T& v) {
		q.push(v);
		if (q.size() > queue_len)
			q.pop();
	}
	queue_t& get_queue() { return q; }
	size_t size() const { return q.size(); }
	T first() const { return q.front(); }
	T last() const { return q.back(); }
private:
	std::queue<T> q;
	size_t queue_len;
};

class TrackPoint2D_t {
public:
	TrackPoint2D_t(double x_, double y_) :X(x_), Y(y_) {}
	double X;
	double Y;
};


class AISAssoStatInfo {
public:
	AISAssoStatInfo() :
		MMSI(0),
		MS(0),
		PAF(0),
		ShipClass(5) {
	}
public:
	int MMSI;
	double MS;
	int PAF;
	uint8_t ShipClass; //AIS类别(5-未知类别)
};


class TrackInfo {
public:
	TrackInfo();
	TrackInfo(unsigned int ID, TentativeTrack& trace);
	virtual ~TrackInfo();
public:
	bool is_maneuvering(double* factor) const;
	void calc_velocity();
	double residual_mean() const; //残差均值
	double residual() const; //当前的残差
public:
	unsigned int	trackID;		//航迹ID
	int64_t			timeSecFromEpoch;//时间戳(毫秒)
	UnscentedKalmanFilter			UKF;			//滤波器实例
	size_t			AtSize;			//当前周期关联的量测数量
	double velocity_value;			//合成的速度值(m/s)
	double velocity_heading;		//合成的速度方向
	int history;					//已跟踪帧数
	int numberOfVisibleFrame;		//目标可见帧数
	int numberOfConsecutiveInvisible;			//目标不可见帧数
	FIFO<double>	residual_z_norm_value_queue; //保存历史的新息归一化数值
	FIFO<double>	velocity_value_queue;		//保存历史的速度信息
	MatrixXd		Q_ORI;						//保存原始的滤波器过程噪声
	int				type;						//航迹类型
	FixLengthQueue<TrackPoint2D_t>	track_point_seq;//保存历史航迹点序列
	double ClutterDense;
	bool	ready_to_report;//目标跟踪是否已经稳定，准备进行航迹的上报
	//----------------------后处理数据-----------------------//
	TrackyMovementStatus_t		movement_status; //目标移动状态
	double			longitude;		//经度
	double			latitude;		//纬度
	//------------------------------------------------------
	AISAssoStatInfo ais_asso;	//AIS关联信息
	std::string	object_id;		//唯一标识字符串
	time_t creatTimeStamp;		//航迹创建时间
};

#endif